/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stud.cp.user.plugins.designer;

import java.util.List;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import stud.cp.core.dbaccess.DAOException;
import stud.cp.core.plugins.Plugin;
import stud.cp.core.plugins.PluginConst;
import stud.cp.core.plugins.PluginRouter;
import stud.cp.core.plugins.WrongPageRequest;
import stud.cp.user.dbaccess.OracleDAOFactory;
import stud.cp.user.valueobjects.Property;
import stud.cp.user.valueobjects.PropertyGroup;
import stud.cp.user.valueobjects.PropertyType;
import stud.cp.user.valueobjects.PropertyTypeDef;
import stud.cp.user.valueobjects.WeaponType;

/**
 * Бин, отвечающий за работу со свойствами.
 * @author Morfant
 */
@Stateless
public class PropetiesPluginBean implements PropetiesPluginLocal {

    /**
     * Фабрика DAO классов.
     */
    private OracleDAOFactory oracleDAOFactory = null;
    /**
     * Логгер.
     */
    private static Logger logger = Logger.getLogger("CPTNP");

    /**
     * Основной метод бизнеслогики.
     * @param req Реквест.
     * @return Класс роутер.
     */
    @Override
    public PluginRouter perform(HttpServletRequest req) {
        String subaction = req.getParameter(PluginConst.SUBACTION);

        if ((subaction != null) && (!subaction.equals(""))) {
            try {
                oracleDAOFactory = new OracleDAOFactory();
                oracleDAOFactory.initialize();
                /* Список действий которые могут выполниться. */
                /*Список данных*/
                if (subaction.equals(PluginConst.GET_LIST)) {
                    return getListPage(req);
                }

                /*Страница добавления*/
                if (subaction.equals(PluginConst.GET_ADD_PAGE)) {
                    return getAddPage(req);
                }

                /*Добавление новых данных*/
                if (subaction.equals(PluginConst.NEW_DATA)) {
                    return newData(req);
                }

                /*Страница редактирования*/
                if (subaction.equals(PluginConst.GET_EDIT_PAGE)) {
                    return getEditPage(req);
                }

                /*Сохранение измененных данных*/
                if (subaction.equals(PluginConst.SAVE_DATA)) {
                    return saveData(req);
                }

                /*Страница удаления*/
                if (subaction.equals(PluginConst.GET_DELETE_PAGE)) {
                    return getDeletePage(req);
                }

                /*Удаление данные*/
                if (subaction.equals(PluginConst.DELETE_DATA)) {
                    return deleteData(req);
                }
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Действия для данного типа поддействия не найдено. Тип поддействия = " + subaction);
            } catch (DAOException ex) {
                logger.debug("Error due access to database. "
                        + "Plugin = PropertiesPluginBean. "
                        + "Subaction=" + subaction, ex);
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Ошибка доступа к данным. " + ex.getMessage());
            } catch (WrongPageRequest ex) {
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Данные из реквеста ошибочны :\n" + ex.getMessage());
            } finally {
                if (oracleDAOFactory != null) {
                    try {
                        oracleDAOFactory.cleanUp();
                    } catch (DAOException ex) {
                        logger.debug("Error due access to database. "
                                + "Plugin = PropertiesPluginBean. "
                                + "Subaction=" + subaction, ex);
                        req.setAttribute(PluginConst.ERROR_MESSAGE,
                                "Ошибка доступа к данным. " + ex.getMessage());
                    }
                }
            }
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE,
                    "Тип поддействия не задан.");
        }
        return new PluginRouter("/errorpage.jsp");
    }

    /**
     * Метод, который позволяет получить
     * список данных запрашиваемого типа.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getListPage(HttpServletRequest req) throws DAOException {
        req.setAttribute(PluginConst.PROPERTIES_LIST, oracleDAOFactory.getPropertiesDAO().getAll());
        return new PluginRouter("/Designer/Property/PropertiesTable.jsp");
    }

    /**
     * Метод, который позволяет получить
     * страницу добавления.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     */
    private PluginRouter getAddPage(HttpServletRequest req) throws DAOException {
//                String[] property_type_list = req.getParameterValues(PluginConst.PROPERTY_TYPE_ID);
//        String[] property_group_list = req.getParameterValues(PluginConst.PROPERTY_GROUP_ID);
//        String property_name = req.getParameter(PluginConst.PROPERTY_NAME);
        String property_type = req.getParameter(PluginConst.PROPERTY_TYPE_ID);
        String property_group = req.getParameter(PluginConst.PROPERTY_GROUP_ID);
        String property_name = req.getParameter(PluginConst.PROPERTY_NAME);
        if ((property_type != null)) {/* Работа с конкретными выдами атрибутов */
            req.setAttribute(PluginConst.PROPERTY_TYPE_ID, new Integer(property_type));
            if (property_type.equals(PluginConst.REFERENCE_TYPE)) {
                List<WeaponType> listOfWeaponType = oracleDAOFactory.getWeaponTypesDAO().getAll();
                req.setAttribute(PluginConst.WEAPON_TYPES_LIST, listOfWeaponType);
            }
            if (property_type.equals(PluginConst.LIST_TYPE)) {
                List<PropertyTypeDef> listOfPropertyTypeDef = oracleDAOFactory.getPropertyTypeDefsDAO().getAllDefForListValue();
                req.setAttribute(PluginConst.LIST_VALUE_DEF_LIST, listOfPropertyTypeDef);
            }
        }
        if (property_name != null) {/* Оставляем имя свойства при изменении типа свойства.*/
            req.setAttribute(PluginConst.PROPERTY_NAME, property_name);
        }
        if ((property_group != null)) {
            req.setAttribute(PluginConst.PROPERTY_GROUP_ID, new Integer(property_group));
        }
        List<PropertyGroup> listOfGroup = oracleDAOFactory.getPropertyGroupsDAO().getAll();
        List<PropertyType> listOfType = oracleDAOFactory.getPropertyTypesDAO().getAll();
        req.setAttribute(PluginConst.PROPERTY_GROUPS_LIST, listOfGroup);
        req.setAttribute(PluginConst.PROPERTY_TYPES_LIST, listOfType);
        return new PluginRouter("/Designer/Property/AddProperty.jsp");
    }

    /**
     * Метод, который позволяет
     * перейти на страницу редактирования данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getEditPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_id = req.getParameter(PluginConst.PROPERTY_ID);
        if (property_id != null) {
            Property property = oracleDAOFactory.getPropertiesDAO().getById(new Integer(property_id));
            if (property != null) {
                List<PropertyGroup> listOfGroup = oracleDAOFactory.getPropertyGroupsDAO().getAll();
                if (property.getProperty_type_defs_id() != null) {
                    PropertyTypeDef propertyTypeDef =
                            oracleDAOFactory.getPropertyTypeDefsDAO().getById(property.getProperty_type_defs_id());
                    req.setAttribute(PluginConst.LIST_VALUE_DEF, propertyTypeDef);
                }
                req.setAttribute(PluginConst.PROPERTY, property);
                req.setAttribute(PluginConst.PROPERTY_GROUPS_LIST, listOfGroup);
                return new PluginRouter("/Designer/Property/EditProperty.jsp");
            } else {
                throw new WrongPageRequest("Свойства с таким id=" + property_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID свойства не задан.");
        }
    }

    /**
     * Метод, который позволяет
     * перейти на страницу удаления элемента.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getDeletePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_id = req.getParameter(PluginConst.PROPERTY_ID);
        if (property_id != null) {
            Property property = oracleDAOFactory.getPropertiesDAO().getById(new Integer(property_id));
            if (property != null) {
                req.setAttribute(PluginConst.PROPERTY, property);
                return new PluginRouter("/Designer/Property/DeletePropety.jsp");
            } else {
                throw new WrongPageRequest("Свойства с таким id=" + property_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID  свойства не заданн.");
        }
    }

    /**
     * Метод, удаляющий данные из базы данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter deleteData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_id = req.getParameter(PluginConst.PROPERTY_ID);
        if (property_id != null) {
            Property property = oracleDAOFactory.getPropertiesDAO().getById(new Integer(property_id));
            if (property != null) {
                oracleDAOFactory.getPropertiesDAO().delete(property.getProperty_id());
                return new PluginRouter("property-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_LIST, false);
            } else {
                throw new WrongPageRequest("Свойства с таким id=" + property_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID свойства не задан..");
        }
    }

    /**
     * Сохранение данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter saveData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_name = req.getParameter(PluginConst.PROPERTY_NAME);
        String[] property_group = req.getParameterValues(PluginConst.PROPERTY_GROUP);
        String property_id = req.getParameter(PluginConst.PROPERTY_ID);
        /*Группа проверок на заполненность данных. */
        String error_message = "";

        if (property_id == null) {
            error_message = "ID свойства должен быть задан";
        }
        if (property_group == null) {
            error_message = error_message + "Группа свойства не опредлена. ";
        }
        if (!error_message.equals("")) {
            throw new WrongPageRequest(error_message);
        }

        if ((property_name == null) || (property_name.equals(""))) {
            error_message = "Имя свойства должно быть заполнено. ";
        }

        if (error_message.equals("")) {
            Property property = oracleDAOFactory.getPropertiesDAO().getById(new Integer(property_id));
            if (property != null) {
                property.setName(property_name);
                property.setProperty_group_id(new Integer(property_group[0]));
                oracleDAOFactory.getPropertiesDAO().update(property);
                return new PluginRouter("property-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_LIST, false);
            } else {
                throw new WrongPageRequest("Свойства с таким id=" + property_id + " не существует. ");
            }
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE, error_message);
            return getEditPage(req);
        }
    }

    /**
     * Метод, позволяющий добавлять новые данные.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter newData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_name = req.getParameter(PluginConst.PROPERTY_NAME);
        String property_type_id = req.getParameter(PluginConst.PROPERTY_TYPE_ID);
        String property_group_id = req.getParameter(PluginConst.PROPERTY_GROUP_ID);
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);//Тип объекта, на который будем ссылаться
        String lise_value_type_def_id = req.getParameter(PluginConst.LIST_VALUE_DEF_ID);//Набор значений.
        /*Группа проверок на заполненность данных. */
        String error_message = "";

        if ((property_type_id == null)) {
            error_message = error_message + "Тип свойства не опредлен. ";
        }
        if ((property_group_id == null)) {
            error_message = error_message + "Группа свойства не опредлена. ";
        }

        if (error_message.equals("")) {
            if (property_type_id.equals(PluginConst.REFERENCE_TYPE)) {
                if ((weapon_type_id == null)) {
                    error_message = error_message + "Типы оружия не заданы.";
                }
            }
            if (property_type_id.equals(PluginConst.LIST_TYPE)) {
                if (lise_value_type_def_id == null) {
                    error_message = error_message + "Наборы значений не заданы.";
                }
            }
        }

        if (!error_message.equals("")) {
            throw new WrongPageRequest(error_message);
        }

        if ((property_name == null) || (property_name.equals(""))) {
            error_message = "Имя свойства должно быть заполнено. ";
        }
        if (error_message.equals("")) {
            Integer property_type_def_id = null;
            if (property_type_id.equals(PluginConst.REFERENCE_TYPE)) {
                property_type_def_id =
                        oracleDAOFactory.getPropertyTypeDefsDAO().
                        create(new PropertyTypeDef(new Integer(weapon_type_id), weapon_type_id));
            }
            if (property_type_id.equals(PluginConst.LIST_TYPE)) {
                property_type_def_id = new Integer(lise_value_type_def_id);
            }
            Property newProperty = new Property(new Integer(property_type_id),
                    new Integer(property_group_id),
                    property_name,
                    property_type_def_id);
            oracleDAOFactory.getPropertiesDAO().
                    create(newProperty);
            return new PluginRouter("property-action.do"
                    + "?"
                    + PluginConst.SUBACTION
                    + "="
                    + PluginConst.GET_LIST, false);
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE, error_message);
            return getAddPage(req);
        }
    }
}
